package Ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.ToolTipManager;
import javax.swing.WindowConstants;

import Model.Space;


/*
 * @author Roch San Buenaventura
 */

public class Display extends JFrame
{
	
	Dimension screen_ = Toolkit.getDefaultToolkit().getScreenSize();
	int width_ = screen_.height - 150;
	int height_ = screen_.height - 150;
	int scaleWidth_ = 12, scaleHeight_ = 7;
	SpacePanel[][] spaces_ = new SpacePanel[40][2];
	int spacePos = 0;
	int spacesAcross_ = 9;
	int sizeAcross_ = (int)(height_ / scaleWidth_) * spacesAcross_;
	double spaceScale_ = .85;
	int boxSize_ = (int)(width_ / scaleWidth_) * 2 - scaleHeight_;
	int pos_ = boxSize_ + scaleHeight_;
	int spacePos_=0;
	int spaceWidth_ = (int)(height_ / scaleWidth_);
	int TopLeftGo_ = pos_ + sizeAcross_;
	int RightEdge_ = pos_ + sizeAcross_ + boxSize_;
	HashMap<String, SpacePanel> spaceMap_ = null;
	
	static final long serialVersionUID = 1;
	
	public Display ()
	{
		this.setSize(screen_.width, screen_.height);
		this.setTitle("Monopoly Game! By: RSB, PC, MdL");
		this.setUndecorated(true);

		ToolTipManager.sharedInstance().setInitialDelay(0); 
		
		JDesktopPane board_ = new JDesktopPane();
		board_.setBackground(Color.black);
		board_.setSize(800, 600);
		board_.setLayout(null);

		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		

		DisplayAssembler.getInstance().setDesktopPane(board_);
		DisplayAssembler.getInstance().setBoxSize(boxSize_);
		DisplayAssembler.getInstance().setRightEdge(RightEdge_);
		DisplayAssembler.getInstance().setSpaceWidth(spaceWidth_);
		DisplayAssembler.getInstance().setTopLeftGo(TopLeftGo_);
		
		this.add(board_);
		this.setVisible(true);
		board_.setVisible(true);
	}
	
	public void showBoard(Space[] board) 
	{
		int start;
		
		String boardpics[] = new String[41];
		
		boardpics[0] = "Go";
		boardpics[1] = "Mediterranean Avenue";
		boardpics[2] = "communitychestbot";
		boardpics[3] = "Baltic Avenue";
		boardpics[4] = "Income Tax";
		boardpics[5] = "Reading Railroad";
		boardpics[6] = "Oriental Avenue";
		boardpics[7] = "chancebot";
		boardpics[8] = "Vermont Avenue";
		boardpics[9] = "Connecticut Avenue";
		boardpics[10] = "In Jail";
		boardpics[11] = "St Charles Place";
		boardpics[12] = "Electric Company";
		boardpics[13] = "States Avenue";
		boardpics[14] = "Virginia Avenue";
		boardpics[15] = "Pennsylvania Railroad";
		boardpics[16] = "St James Place";
		boardpics[17] = "communitychestleft";
		boardpics[18] = "Tennessee Avenue";
		boardpics[19] = "New York Avenue";
		boardpics[20] = "Free Parking";
		boardpics[21] = "Kentucky Avenue";
		boardpics[22] = "chancebot";
		boardpics[23] = "Indiana Avenue";
		boardpics[24] = "Illinois Avenue";
		boardpics[25] = "B & O Railroad";
		boardpics[26] = "Atlantic Avenue";
		boardpics[27] = "Ventnor Avenue";
		boardpics[28] = "Water Works";
		boardpics[29] = "Marvin Gardens";
		boardpics[30] = "Go To Jail";
		boardpics[31] = "Pacific Avenue";
		boardpics[32] = "North Carolina Avenue";
		boardpics[33] = "communitychestright";
		boardpics[34] = "Pennsylvania Avenue";
		boardpics[35] = "Shortline Railroad";
		boardpics[36] = "chanceright";
		boardpics[37] = "Park Place";
		boardpics[38] = "Luxury Tax";
		boardpics[39] = "Boardwalk";
		
		int bp = 0;
		Color c = new Color(0, 0, 0);

		addLabel(board[bp++], false, pos_ + sizeAcross_, pos_ + sizeAcross_, boxSize_, boxSize_, c, true, boardpics[bp-1]);

		c = new Color(97, 73, 121);
		start = 8;
		addSmallOp(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start--), 0, c, true, true);
		addSmallOp(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start--), 0, new Color(0, 0, 0), false, true);
		addSmallOp(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start--), 0, c, true, true);
		addSmallOp(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start--), 0, new Color(0, 0, 0), false, true);
		
		c = new Color(85, 141, 215);
		addSmallOp(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start--), 0, new Color(0, 0, 0), false, true);
		addSmallOp(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start--), 0, c, true, true);
		addSmallOp(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start--), 0, new Color(0, 0, 0), false, true);
		addSmallOp(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start--), 0, c, true, true);
		addSmallOp(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start--), 0, c, true, true);
		
		addLabel(board[bp++], false, scaleHeight_, pos_ + sizeAcross_, boxSize_, boxSize_, c, true, boardpics[bp-1]);
		
		start = 8;
		c = new Color(148, 55, 53);
		addSmall(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start--), c, true, false);
		addSmall(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start--), new Color(0, 0, 0), false, false);
		addSmall(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start--), c, true, false);
		addSmall(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start--), c, true, false);
		
		c = new Color(228, 108, 12);
		addSmall(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start--), new Color(0, 0, 0), false, false);
		addSmall(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start--), c, true, false);
		addSmall(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start--), new Color(0, 0, 0), false, false);
		addSmall(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start--), c, true, false);
		addSmall(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start--), c, true, false);
		
		addLabel(board[bp++], false, scaleHeight_, scaleHeight_, boxSize_, boxSize_, c, true, boardpics[bp-1]);
		
		start = 0;
		c = new Color(255, 0, 0);
		addSmall(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start++), 0, c, true, true);
		addSmall(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start++), 0, new Color(0, 0, 0), false, true);
		addSmall(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start++), 0, c, true, true);
		addSmall(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start++), 0, c, true, true);
		addSmall(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start++), 0, new Color(0, 0, 0), false, true);
		
		c = new Color(255, 255, 0);
		addSmall(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start++), 0, c, true, true);
		addSmall(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start++), 0, c, true, true);
		addSmall(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start++), 0, new Color(0, 0, 0), false, true);
		addSmall(boardpics[bp], board[bp++], pos_ + (spaceWidth_ * start++), 0, c, true, true);
		
		addLabel(board[bp++], false, pos_ + sizeAcross_, scaleHeight_, boxSize_, boxSize_, c, true, boardpics[bp-1]);
		
		c = new Color(79, 99, 40);
		start = 0;
		addSmallOp(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start++), c, true, false);
		addSmallOp(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start++), c, true, false);
		addSmallOp(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start++), new Color(0, 0, 0), false, false);
		addSmallOp(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start++), c, true, false);
		addSmallOp(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start++), new Color(0, 0, 0), false, false);
		
		c = new Color(39, 63, 97);
		addSmallOp(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start++), new Color(0, 0, 0), false, false);
		addSmallOp(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start++), c, true, false);
		addSmallOp(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start++), new Color(0, 0, 0), false, false);
		addSmallOp(boardpics[bp], board[bp++], 0, pos_ + (spaceWidth_ * start++), c, true, false);

		JLabel label = new JLabel();
		label.setOpaque(true);
		
		try
		{
			label.setIcon(new ImageIcon(scaleImage(new FileInputStream("MonopolyImages/Spaces/center.jpg"),
					sizeAcross_, sizeAcross_)));
		} 
		
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		
		label.setSize(new Dimension(sizeAcross_, sizeAcross_));
		label.setBorder(BorderFactory.createLineBorder(Color.black));
		DisplayAssembler.getInstance().addComponent(label, new Point(pos_, pos_), 
				JLayeredPane.FRAME_CONTENT_LAYER);
	}
	
	void addSmall(String imageName, Space space, int x, int y, Color c, boolean isProp, boolean isVert)
	{

		int panelWidth;
		
		if (isProp)
			panelWidth = (int)(spaceScale_ * boxSize_);
		
		else
			panelWidth = boxSize_;
		
		int panelHeight;
		
		if (isVert) 
		{
			panelHeight = panelWidth;
			panelWidth = height_ / scaleWidth_;
			y += scaleHeight_;
		}
		
		else 
		{
			panelHeight = height_ / scaleWidth_;
			x += scaleHeight_;
		}
		
		addLabel(space, isProp, x, y, panelWidth, panelHeight,c, true, imageName);
		

		if (isProp) 
		{
			panelWidth = boxSize_ - Math.max(panelWidth, panelHeight);
			
			if (isVert) 
			{
				panelHeight = panelWidth;
				panelWidth = (int)height_ / scaleWidth_;
			}
	
			if (isVert)
				
				addLabel(space, isProp, x, y + (int)(spaceScale_ * boxSize_), panelWidth,
						panelHeight, c, false, imageName);
			
			else
				addLabel(space, isProp, x + (int)(spaceScale_ * boxSize_), y, panelWidth, 
						panelHeight, c, false, imageName);	
		}
	}

	void addSmallOp(String imageName, Space space, int x, int y, Color c, boolean isProp, boolean isVert) {
	
		int panelWidth;

		if (isProp)
			panelWidth = (int)(spaceScale_ * boxSize_);
		
		else
			panelWidth = boxSize_;
		
		int panelHeight;
		
		if (isVert) 
		{
			panelHeight = panelWidth;
			panelWidth = height_ / scaleWidth_;
		}
		
		else 
			panelHeight = height_ / scaleWidth_;

		if(isVert)
			y += pos_ + sizeAcross_;
		
		else
			x += pos_ + sizeAcross_;

		int panelWidthS = panelWidth, panelHeightS = panelHeight;
		
		if (isProp)
		{
			panelWidthS = boxSize_ - Math.max(panelWidth, panelHeight);
			
			if (isVert)
			{
				panelHeightS = panelWidthS;
				panelWidthS = height_ / scaleWidth_;
			}
			
			addLabel(space, isProp, x, y, panelWidthS, panelHeightS, c, false, imageName);
		} 
		
		else 
		{
			panelWidthS = 0;
			panelHeightS = 0;
		}
		
		if (isVert)
			addLabel(space, isProp, x, y + panelHeightS, panelWidth, panelHeight, c, true, imageName);
		
		else
			addLabel(space, isProp, x + panelWidthS, y, panelWidth, panelHeight, c, true, imageName);	
	}


	void addLabel(Space space, boolean isProp, int x, int y, int width, int height, 
			Color c, boolean useTex, String imageName)
	{
		new SpacePanel(spacePos_++, space, isProp, x, y, width, height, c, useTex, imageName);
	}
	
	public Point getCenter(int spaceNum)
	{
		return spaces_[spaceNum][0].getCenter();
	}
	
	public static BufferedImage scaleImage(InputStream p_image, int p_width, int p_height)
	{
	   InputStream imageStream = new BufferedInputStream(p_image);
	   Image image = null;
		
	   try 
	   {
			image = (Image) ImageIO.read(imageStream);
	   } 
	   
	   catch (IOException e) 
	   {
			e.printStackTrace();
	   } 
	 
        BufferedImage thumbImage = new BufferedImage(p_width, 
          p_height, BufferedImage.TRANSLUCENT);
        Graphics2D graphics2D = thumbImage.createGraphics();
        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
          RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics2D.drawImage(image, 0, 0, p_width, p_height, null);
 
        return thumbImage;        
    }
}